#此脚本为质检所需函数包

import re


#sent为句子行
#pron为音标行
#stpn为句子行或音标行均可

#根据位置获取单词
def get_char_word(sent,charnum,spl=None):
    wordlist=[s.strip() for s in sent.split(spl) if s.strip()]
    spltpos=[i for i,j in enumerate(sent) if j==spl]
    if charnum<=spltpos[0]:
        return wordlist[0]
    if charnum>=spltpos[-1]:
        return wordlist[-1]
    for n in range(0,len(spltpos)-1):
        if spltpos[n]<=charnum<=spltpos[n+1]:
            return wordlist[n+1]



#空格问题

def dotsplash_space(pron):
    '''检查音标行的.和/前后是否有空格，默认第一个字符和最后一个字符不是.和/'''
    erlist=[]
    for i in range(1,len(pron)-1):
        if pron[i] in ['.','/']:
            if pron[i-1]!=' ' or pron[i+1]!=' ':
                erlist.append(get_char_word(pron,i,'/'))
    return erlist

def more_space_continue(stpn):
    '''检查句子行或音标行是否存在连续空格'''
    if re.search(r' {2,}',stpn):
        return True
    else:
        return False

def more_space_num(pron):
    '''检查音标行数字前是否存在空格，默认第一个字符不是数字'''
    erlist=[]
    for i in range(1,len(pron)):
        if re.search(r'[0-9]',pron[i]):
            if pron[i-1]==' ':
                erlist.append(get_char_word(pron,i,'/'))
    return erlist

#结尾字符

def end_char(stpn,endchar):
    '''检查句子行或音标行末尾字符是否在endchar中'''
    if stpn[-1] in endchar:
        return True
    return False

#标点
#连续标点
def continue_pronuc(stpn,pc):
    '''检查句子行或音标行是否出现连续的pc或pc间只存在空格的情况'''
    if re.search(pc+r' *'+pc,stpn):
        return True
    return False

#标点规则

#文本标点位置
def pronuc_pos(sent,targetpron,pronucset,charset):
    erlist=[]
    if sent[0] not in charset:
        erlist.append('开头不是合法字符')
    for i in range(len(sent.strip())-1):
        if sent[i] in targetpron:
            if sent[i-1] not in charset or sent[i+1] not in pronucset+[' ']:
                erlist.append(get_char_word(sent,i,' '))
    if sent[-1] == '%':
        if sent[-2] not in charset:
            erlist.append('结尾符号错误')
    elif sent[-2] == '%':
        if sent[-1] not in pronucset:
            erlist.append('结尾符号错误')
    else:
        erlist.append('结尾符号错误')
    return erlist

#非法标点检查

def sent_end_pronc(sent,bigpron,pronucset):
    '''检查句末标点'''
    if sent[-1] in bigpron and sent[-2] in pronucset:
        return False
    else:
        return True

def find_quanjiao(stpn):
    '''检查句子行或标点行是否出现全角字符'''
    if re.findall(r'[\uFF00-\uFFFF\u3000]',stpn):
        return True
    return False
#音节

def no_yuanyin(pron,yuanyinset):
    '''检查音节是否缺少元音'''
    erlist=[]
    yinjie=[p.strip() for p in pron.split('/') if p.strip()]
    for yj in yinjie:
        yjl=[y.strip() for y in yj.split('.') if y.strip()]
        if yjl[-1] in ['f r','f l','b r', 'b l','k r','k l','g r','g l','t r','d r']:
            if len(yjl)==1:
                erlist.append(yjl[-1])
                continue
            else:
                preyjl=yjl[-2]
                sylist=[syl.strip() for syl in preyjl.split(' ') if syl.strip()]
                if re.sub('[0-9]+','',sylist[-1]) in yuanyinset:
                    endsingle=yjl.pop()
        for tyj in yjl:
            sylist=[syl.strip() for syl in tyj.split(' ') if syl.strip()]
            flag=0
            for s in sylist:
                if re.sub('[0-9]+','',s) in yuanyinset:
                    flag+=1
            if flag==0:
                erlist.append(tyj)
    return erlist

def more_yuanyin(pron,yuanyinset):
    '''检查音节是否多元音'''
    erlist=[]
    yinjie=[p.strip() for p in pron.split('/') if p.strip()]
    for yj in yinjie:
        yjl=[y.strip() for y in yj.split('.') if y.strip()]
        for tyj in yjl:
            sylist=[syl.strip() for syl in tyj.split(' ') if syl.strip()]
            flag=0
            for s in sylist:
                if re.sub('[0-9]+','',s) in yuanyinset:
                    flag+=1
            if flag>1:
                erlist.append(tyj)
    return erlist

#重音

def stress_num(pron):
    '''检查音节重音数量'''
    erlist=[]
    pronlist=[p.strip() for p in pron.split('/') if p.strip()]
    for p in pronlist:
        if len(re.findall('1',p))>1:
            erlist.append(p)
    return erlist

def stress_errornum(pron):
    '''检查重音标记数字是否错误，句重音是否在词尾，词重音与句重音错误'''
    erlist=[]
    if re.search(r'[024-9]',pron):
        return True
    pronlist=[p.strip() for p in pron.split('/') if p.strip()]
    for p in pronlist:
        if '3' in p and p[-1]!='3':
            erlist.append(p)
    return erlist

def stress_existnum(pron):
    '''检查无词重音和句重音情况'''
    erlist=[]
    if not re.search('3',pron):
        return True
    pronlist=[p.strip() for p in pron.split('/') if p.strip()]
    for p in pronlist:
        if len(re.findall('1',p))<1:
            erlist.append(p)
    return erlist
def stress_wordend(pron,yuanyinset):
    '''检查重音是否在词末元音'''
    erlist=[]
    pronlist=[p.strip() for p in pron.split('/') if p.strip()]
    for p in pronlist:
        sylist=[s.strip() for s in p.split('.') if s.strip()]
        ends=sylist[-1]
        el=[e.strip() for e in ends.split(' ') if e.strip()]
        for e in el:
            if re.sub(r'[0-9]+','',e) in yuanyinset:
                if not re.search(r'[0-9]',e[-1]):
                    erlist.append(ends)
    return erlist

#音素合法性

def illegal_phoneme(pron,phonemeset):
    '''检查是否出现不合法音素，可用于检查音素间缺少空格'''
    erlist=[]
    pron=re.sub('[0-9]+','',pron)
    pronlist=[p.strip() for p in re.split(r'[ /.]',pron) if p.strip()]
    for p in pronlist:
        if re.sub(r'[0-9]+','',p) not in phonemeset:
            #print(p)
            erlist.append(p)
    return erlist

#文本音标行对齐

def pronsent_num(sent,pron):
    '''检查单词数与音标数是否一致，单词按空格划分，音标按斜杠划分'''
    if len(sent.split())!=len(pron.split('/')):
        return True
    return False


#文本内容检查

def sent_num(sent):
    '''检查文本行是否出现文本'''
    if re.search(r'[0-9]',sent):
        return True
    return False
